import axios from "axios";
import { ElMessage } from "element-plus";
import { formatToLocalDateTime } from "./date";
import { getToken, isValidToken, setToken } from "./auth";
import { useUserStore } from "@/stores/user";
import router from "@/router";

// 基础配置
const createAxiosInstance = (config) => {
  return axios.create({
    baseURL: process.env.VUE_APP_API_URL,
    timeout: config.timeout || 15000,
    ...config,
  });
};

// 创建主请求实例和刷新token实例
const request = createAxiosInstance({ retry: 2, retryDelay: 1000 });
const refreshTokenRequest = createAxiosInstance({ timeout: 5000 });

// Token刷新相关
let isRefreshing = false;
let refreshSubscribers = [];

const subscribeTokenRefresh = (callback) => {
  refreshSubscribers.push(callback);
};

const onTokenRefreshed = (token) => {
  refreshSubscribers.forEach((callback) => callback(token));
  refreshSubscribers = [];
};

const refreshToken = async () => {
  try {
    const res = await refreshTokenRequest.post("/auth/refreshToken");
    if (res.data.success) {
      setToken(res.data.data);
      return res.data.data;
    }
    return null;
  } catch (error) {
    return null;
  }
};

// 处理日期范围参数
const handleDateRange = (params) => {
  if (params?.dateRange && Array.isArray(params.dateRange)) {
    const [startTime, endTime] = params.dateRange;
    params.startTime = startTime ? formatToLocalDateTime(startTime) : undefined;
    params.endTime = endTime ? formatToLocalDateTime(endTime) : undefined;
    delete params.dateRange;
  }
  return params;
};

// 请求拦截器
request.interceptors.request.use(
  async (config) => {
    const token = getToken();
    if (!token) return config;

    if (!isValidToken(token) && !config.url.includes("/auth/")) {
      if (!isRefreshing) {
        isRefreshing = true;
        const newToken = await refreshToken();
        isRefreshing = false;

        if (newToken) {
          onTokenRefreshed(newToken);
          config.headers["Authorization"] = `Bearer ${newToken}`;
          return config;
        }

        const userStore = useUserStore();
        userStore.logout();
        router.push("/login");
        return Promise.reject(new Error("登录已过期"));
      }

      return new Promise((resolve) => {
        subscribeTokenRefresh((token) => {
          config.headers["Authorization"] = `Bearer ${token}`;
          resolve(config);
        });
      });
    }

    config.headers["Authorization"] = `Bearer ${token}`;
    config.params = handleDateRange(config.params);
    config.data = handleDateRange(config.data);
    return config;
  },
  (error) => Promise.reject(error)
);

// 响应拦截器
request.interceptors.response.use(
  async (response) => {
    // 如果是二进制流，直接返回响应对象
    if (response.config.responseType === "blob") {
      return response;
    }

    const res = response.data;
    console.log(res.success);
    if (!res.success && res.success !== undefined) {
      ElMessage.error(res.message || "请求失败");

      if (res.status === "401") {
        const newToken = await refreshToken();
        if (newToken) {
          return request(response.config);
        }
        const userStore = useUserStore();
        userStore.logout();
        router.push("/login");
      }
    }
    return res;
  },
  (error) => {
    // 处理超时重试
    if (error.code === "ECONNABORTED" && error.message.includes("timeout")) {
      const config = error.config;
      config.__retryCount = config.__retryCount || 0;

      if (config.__retryCount < config.retry) {
        config.__retryCount += 1;
        return new Promise((resolve) => {
          setTimeout(() => resolve(axios(config)), config.retryDelay || 1000);
        });
      }
    }

    // 处理错误响应
    if (error.response) {
      const { status } = error.response;
      let errorMsg = "网络请求失败";
      if (status === 401) {
        errorMsg = "登录已过期";
      }
      if (status === 403) {
        errorMsg = "权限验证失败，请联系管理员!";
      }
      ElMessage.error(errorMsg);
    } else {
      ElMessage.error(error.message || "网络请求失败");
    }

    return {
      success: false,
      message: error.message || "网络请求失败",
      errorCode: error.response?.status || "NETWORK_ERROR",
      data: null,
    };
  }
);

export default request;
